﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace A3ServiceHost
{
    public class Program
    {
        static void Main(string[] args)
        {
            ServiceHost myService = new ServiceHost(typeof(A3ServiceLibrary.AuthenticationService));

            myService.Open();

            AuthenticationListener auth_listener = new AuthenticationListener();
            auth_listener.Open();

            AuthenticationSender auth_test = new AuthenticationSender();
            auth_test.Go();

            Console.WriteLine("Press any key to stop.");
            Console.ReadLine();

            auth_listener.Dispose();
            auth_test.Dispose();

            if (myService.State != CommunicationState.Closed)
                myService.Close();            
        }
    }

    [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
    class AuthenticationListener : AuthenticationService.IAuthenticationServiceCallback, IDisposable
    {
        private AuthenticationService.AuthenticationServiceClient auth_client;

        public void Open()
        {
            InstanceContext context = new InstanceContext(this);
            auth_client = new AuthenticationService.AuthenticationServiceClient(context, "WSDualHttpBinding_IAuthenticationService");

            auth_client.Subscribe();
        }

        public void OnAuthentication(string username, String password)
        {
            try
            {
                A3ServiceHost.EncryptionService.ServiceSoapClient encryption_client =
                new A3ServiceHost.EncryptionService.ServiceSoapClient("ServiceSoap");

                String decrypt_username = encryption_client.Decrypt(username);
                String decrypt_password = encryption_client.Decrypt(password);
                Console.WriteLine("<<< Received username: {0}[{2}] password: {1}[{3}]", decrypt_username, decrypt_password, username, password);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        public void Dispose()
        {
            auth_client.Unsubscribe();
            auth_client.Close();
        }
    }

    [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
    class AuthenticationSender : AuthenticationService.IAuthenticationServiceCallback, IDisposable
    {
        private AuthenticationService.AuthenticationServiceClient auth_client;

        public void Go()
        {
            try
            {
                InstanceContext context = new InstanceContext(this);
                auth_client = new AuthenticationService.AuthenticationServiceClient(context, "WSDualHttpBinding_IAuthenticationService");

                A3ServiceHost.EncryptionService.ServiceSoapClient encryption_client =
                new A3ServiceHost.EncryptionService.ServiceSoapClient("ServiceSoap");

                for (int i = 0; i < 5; i++)
                {
                    String username = encryption_client.Encrypt("user" + i);
                    String password = encryption_client.Encrypt("password" + i);
                    string message =  "Username: user" + i + "(" + username + ") Password: password" + i + "("+password+")";
                    Console.WriteLine(">>> Sending " + message);
                    auth_client.Authenticate(username, password);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

        }

        public void OnAuthentication(string message, string timestamp)
        {
        }

        public void Dispose()
        {
            auth_client.Close();
        }
    }
}
